"""
验证器工具模块
"""

import re
from pathlib import Path
from typing import List, Optional, Tuple
from .exceptions import FileValidationError


class FileValidator:
    """文件验证器"""
    
    @staticmethod
    def validate_file_extension(filename: str, allowed_extensions: List[str]) -> bool:
        """
        验证文件扩展名
        
        Args:
            filename: 文件名
            allowed_extensions: 允许的扩展名列表
            
        Returns:
            bool: 验证是否通过
        """
        if not filename:
            return False
        
        file_ext = Path(filename).suffix.lower()
        return file_ext in [ext.lower() for ext in allowed_extensions]
    
    @staticmethod
    def validate_file_size(file_size: int, max_size: int) -> bool:
        """
        验证文件大小
        
        Args:
            file_size: 文件大小（字节）
            max_size: 最大允许大小（字节）
            
        Returns:
            bool: 验证是否通过
        """
        return 0 < file_size <= max_size
    
    @staticmethod
    def validate_filename(filename: str) -> Tuple[bool, Optional[str]]:
        """
        验证文件名
        
        Args:
            filename: 文件名
            
        Returns:
            Tuple[bool, Optional[str]]: (是否有效, 错误信息)
        """
        if not filename:
            return False, "文件名不能为空"
        
        # 检查文件名长度
        if len(filename) > 255:
            return False, "文件名过长"
        
        # 检查危险字符
        dangerous_chars = '<>:"/\\|?*'
        for char in dangerous_chars:
            if char in filename:
                return False, f"文件名包含非法字符: {char}"
        
        # 检查保留名称
        reserved_names = [
            'CON', 'PRN', 'AUX', 'NUL',
            'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
            'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
        ]
        
        name_without_ext = Path(filename).stem.upper()
        if name_without_ext in reserved_names:
            return False, f"文件名使用了系统保留名称: {name_without_ext}"
        
        return True, None


class ConversionValidator:
    """转换参数验证器"""
    
    @staticmethod
    def validate_output_format(output_format: str) -> bool:
        """
        验证输出格式
        
        Args:
            output_format: 输出格式
            
        Returns:
            bool: 验证是否通过
        """
        supported_formats = ['docx', 'html', 'pdf']
        return output_format.lower() in supported_formats
    
    @staticmethod
    def validate_template_name(template_name: str) -> bool:
        """
        验证模板名称
        
        Args:
            template_name: 模板名称
            
        Returns:
            bool: 验证是否通过
        """
        if not template_name:
            return True  # 模板是可选的
        
        # 只允许字母、数字、下划线和连字符
        pattern = r'^[a-zA-Z0-9_-]+$'
        return bool(re.match(pattern, template_name))
    
    @staticmethod
    def validate_css_theme(css_theme: str) -> bool:
        """
        验证CSS主题
        
        Args:
            css_theme: CSS主题名称
            
        Returns:
            bool: 验证是否通过
        """
        if not css_theme:
            return True  # CSS主题是可选的
        
        supported_themes = ['default', 'github', 'academic', 'minimal']
        return css_theme.lower() in supported_themes
    
    @staticmethod
    def validate_page_size(page_size: str) -> bool:
        """
        验证页面大小
        
        Args:
            page_size: 页面大小
            
        Returns:
            bool: 验证是否通过
        """
        if not page_size:
            return True  # 页面大小是可选的
        
        supported_sizes = ['A4', 'A3', 'A5', 'Letter', 'Legal']
        return page_size in supported_sizes


class TaskValidator:
    """任务验证器"""
    
    @staticmethod
    def validate_task_id(task_id: str) -> bool:
        """
        验证任务ID
        
        Args:
            task_id: 任务ID
            
        Returns:
            bool: 验证是否通过
        """
        if not task_id:
            return False
        
        # 任务ID应该是UUID格式
        uuid_pattern = r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
        return bool(re.match(uuid_pattern, task_id, re.IGNORECASE))
    
    @staticmethod
    def validate_task_status(status: str) -> bool:
        """
        验证任务状态
        
        Args:
            status: 任务状态
            
        Returns:
            bool: 验证是否通过
        """
        valid_statuses = ['pending', 'processing', 'completed', 'failed']
        return status.lower() in valid_statuses